import { TemplateRef, Type } from '@angular/core';

export class TypeUtils {
  static isNull(value: any): value is null {
    return value === null;
  }

  static isArray(value: any): boolean {
    return Array.isArray(value);
  }

  // 是否是数字, 包含NaN
  static isNumber(value: any): boolean {
    return typeof value === 'number';
  }

  static isString(value: any): value is string {
    return typeof value === 'string';
  }

  static isUndefined(value: any): value is undefined {
    return value === undefined;
  }

  // Angular component
  static isComponent(value: any): value is Type<any> {
    return value instanceof Type;
  }

  static isBoolean(value: any): value is boolean {
    return typeof value === 'boolean';
  }

  static isFunction(obj: any): obj is (...args: any[]) => any {
    return typeof obj === 'function';
  }

  // Angular template
  static isTemplateRef(value: any): value is TemplateRef<any> {
    return value instanceof TemplateRef;
  }

  // Not empty string
  static isRealString(value: any): value is string {
    return typeof value === 'string' && value !== '';
  }

  // 是否是非NaN的数字
  static isValidNumber(value: any): value is number {
    return typeof value === 'number' && !Number.isNaN(value);
  }

  static isNotNil<T>(value: T): value is NonNullable<T> {
    return typeof value !== 'undefined' && value !== null;
  }

  static isObject<T = any>(value: any): value is T {
    return value instanceof Object && !(value instanceof Array);
  }

  static isNil(value: any): value is null | undefined {
    return typeof value === 'undefined' || value === null;
  }
}
